package com.hpc.Controller;

import Utils.JSONUtil;
import Utils.JWTUtil;
import Utils.ResultUtil;
import com.alibaba.fastjson.JSON;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.hpc.Service.OpenFeignService1;
import entity.ResultEnum;
import entity.article;
import entity.comment;
import entity.systemConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@Slf4j
@RequestMapping("/ts/article")
public class articleController1 {
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private com.hpc.Service.articleService articleService;
    @Resource
    private OpenFeignService1 openFeignService;
    /**
     * @author: Liujd
     * @createTime: 2023/5/17 18:00
     * @description: like 对指定文章标记喜欢，用以生成用户的猜你喜欢
     * @param:[userId, articleId]
     * @return:java.lang.String
     */
    @GetMapping("/like")
    public String like(String userId,String articleId){
        String personallike=userId+"_personallike";
        String likesOfarticle= systemConstant.LIKESOFARTICLE;
        article article = articleService.findById(articleId);
        try{
            //将key为id_personallike的数组取出，看有没有喜欢过，若已存在则直接反馈，只允许单次喜欢
            List<article> range = redisTemplate.opsForList().range(personallike, 0, -1);
            List<entity.article> collect = range.stream().filter(a -> a.getSerial().equals(article.getSerial())).collect(Collectors.toList());
            if(!collect.isEmpty()){
               //说明已经喜欢过了
               return JSONUtil.toJSONString(ResultUtil.success());
            }
            //先向redis存用户喜欢的文章，k为用户id_personallike,v为文章实体类
            redisTemplate.opsForList().rightPush(personallike,article);
            //再向redis存对应id文章的喜欢数量
//            Boolean aBoolean = redisTemplate.opsForHash().hasKey(likesOfarticle, articleId);
                redisTemplate.opsForHash().increment(likesOfarticle,articleId,1);
            return JSONUtil.toJSONString(ResultUtil.success());
        }catch (Exception e){
            e.printStackTrace();
            return JSONUtil.toJSONString(ResultUtil.error(ResultEnum.ERROR));
        }

    }
    @GetMapping("/unlike")
    public String unlike(String userId,String articleId){
        String personallike=userId+"_personallike";
        String likesOfarticle= systemConstant.LIKESOFARTICLE;
        article article = articleService.findById(articleId);
        try{
            //先取消用户的个人喜欢
            if(redisTemplate.hasKey(personallike)){
                //将personallike数组去除数组对象中id等于article的
                List<article> range = redisTemplate.opsForList().range(personallike, 0, -1);
                //去除range中id等于articleId的
                if(!range.isEmpty()){
                   range= range.stream().filter(r->!(r.getSerial().equals(articleId))).collect(Collectors.toList());
//                    boolean remove = range.remove(article);
                }
                redisTemplate.delete(personallike);
                if(!range.isEmpty()){
                    redisTemplate.opsForList().rightPushAll(personallike,range);
                }
//                opsResult1 = redisTemplate.opsForList().remove(personallike, 1, article);
            }
//            redisTemplate.opsForList().rightPush(personallike,article.getTitle());
            //再向redis存对应id文章的喜欢数量
//            Boolean aBoolean = redisTemplate.opsForHash().hasKey(likesOfarticle, articleId);
//            if (aBoolean){
            if(redisTemplate.hasKey(likesOfarticle)){
                //取出likeOfarticle键
                Integer count = (Integer) redisTemplate.opsForHash().get(likesOfarticle, articleId);
                if(count > 0){
                    count--;
                }
                redisTemplate.opsForHash().put(likesOfarticle,articleId,count);
//                opsResult2 = redisTemplate.opsForHash().increment(likesOfarticle, articleId, -1);
            }
//            }
//            List<String> range = redisTemplate.opsForList().range(personallike, 0, -1);
//            for (String s : range) {
//                System.out.println(s);
//            }

                return JSONUtil.toJSONString(ResultUtil.success("取消成功"));

        }catch (Exception e){
            e.printStackTrace();
            return JSONUtil.toJSONString(ResultUtil.error(ResultEnum.ERROR));
        }

    }
    /**
     * @author: Liujd
     * @createTime: 2023/5/16 16:40
     * @description: articleRecommend,根据用户喜欢推荐热度前五的文章
     * @param:[userId]
     * @return:java.lang.String
     */
    @GetMapping("/recommend")
    public String articleRecommend(@RequestHeader("userId") String userId){
        //先去redis获取用户喜欢的文章标题集合
        String keyName=userId+"_personallike";
        Boolean aBoolean = redisTemplate.hasKey(keyName);
        if (aBoolean){
            //如果存在当前用户的喜欢数据
            List<article> likes = redisTemplate.opsForList().range(keyName, 0, -1);
            List<String> titles=new ArrayList<String>();
            if (likes.size()!=0){
                for (article like : likes) {
                    titles.add(like.getTitle());
                }
            }
            List<article> recommendArticles = articleService.getRecommendArticles(titles);
            if (recommendArticles.size()>1){
                return JSONUtil.toJSONString(ResultUtil.success(recommendArticles));
            }else {
                List<article> articles = articleService.gethotTop5();
                return JSONUtil.toJSONString(ResultUtil.success(articles));
            }
        }else {
            //不存在则调用一周最热
            List<article> articles = articleService.gethotTop5();
            return JSONUtil.toJSONString(ResultUtil.success(articles));
        }
    }
    /**
     * @author : Liujd
     * @ClassName articleController1
     * @Description 获取一周最热文章数据
     * @date : 16:23 2023/5/16
     * @Version
     **/
    @GetMapping("/hotweekendly")
    public String hotWeekendly(){
        List<article> articles = articleService.gethotTop5();
        return JSONUtil.toJSONString(ResultUtil.success(articles));
    }
    /**
     * @author: Liujd
     * @createTime: 2023/5/16 22:52
     * @description: showArticle阅读文章，展示指定id文章的相信相关信息
     * @param:[articleId, request]
     * @return:java.lang.String
     */
    @GetMapping("/readarticle")
    public String showArticle(String articleId, HttpServletRequest request){
        String token = request.getHeader("token");
        DecodedJWT decodejwt = JWTUtil.decodejwt(token);
        String userid = decodejwt.getClaim("userid").asString();
        Map<String, String> infos = articleService.readArticle(articleId,userid);
        return JSONUtil.toJSONString(ResultUtil.success(infos));
    }
    /**
     * @author: Liujd
     * @createTime: 2023/5/17 17:53
     * @description: comment对指定文章进行评论
     * @param:[articleId, userId, content]
     * @return:java.lang.String
     */
    @PostMapping("/comment")
    public String comment(String articleId,String userId,String content){
        int flag = articleService.addComment(articleId, userId, content);
        if (flag==1){
            List<comment> comments = articleService.getCommentsByArticleId(articleId);
            ArrayList<String> userIds =new ArrayList<>();
            for (comment comment : comments) {
                userIds.add(comment.getUser_id());
            }
            String userIdsJson = JSONUtil.toJSONString(userIds);
            String userInfoOfComment = openFeignService.getUserInfoOfComment(userIdsJson);
            HashMap<String, String> objectObjectHashMap = new HashMap<>();
            objectObjectHashMap.put("newComments",JSON.toJSONString(comments));
            objectObjectHashMap.put("useInfo",userInfoOfComment);
            return JSONUtil.toJSONString(ResultUtil.success(objectObjectHashMap));
        }else {
            return JSONUtil.toJSONString(ResultUtil.error(ResultEnum.ERROR));
        }
    }
    @GetMapping("/deletearticle")
    public String deleteArticle(String articleId,HttpServletRequest request){
        boolean b = articleService.deleteArticle(articleId);
        if (b){
            String token = request.getHeader("token");
            DecodedJWT decodejwt = JWTUtil.decodejwt(token);
            String userid = decodejwt.getClaim("userid").asString();
            List<article> articles = articleService.allArticleByUserId(userid,true);
            return JSONUtil.toJSONString(ResultUtil.success(articles));
        }else {
            return JSONUtil.toJSONString(ResultUtil.error(ResultEnum.ERROR));
        }
    }
    /**
     * @author: Liujd
     * @createTime: 2023/5/16 17:11
     * @description: allArticle获取所有的文章数据
     * @param:[type]类型，0游记1攻略
     * @return:java.lang.String
     */
    @GetMapping("/allarticle")
    public String allArticle(int type){
        List<article> articles = articleService.allArticle(type);
        return JSONUtil.toJSONString(ResultUtil.success(articles));
    }
    @PostMapping("/searchByTitle")
    public String searchArticle(String title){
        List<article> articles = articleService.searchByTitle(title);
        return JSON.toJSONString(ResultUtil.success(articles));
    }
    @PostMapping("/publish")
    public String publishArticle(String content,String title,HttpServletRequest request,String category,String cover){
        String token = request.getHeader("token");
        DecodedJWT decodejwt = JWTUtil.decodejwt(token);
        String userid = decodejwt.getClaim("userid").asString();
        String username=decodejwt.getClaim("username").asString();
        boolean publish = articleService.publish(title, content, userid, category, username,cover);
        if (publish){
            List<article> articles = articleService.allArticleByUserId(userid,true);
            return JSONUtil.toJSONString(ResultUtil.success(articles));
        }else {
            return JSONUtil.toJSONString(ResultUtil.error("发布失败！"));
        }
    }
    @PostMapping("/modifyArticle")
    public String modifyArticle(String content,String title,HttpServletRequest request,int type,String articleId,@RequestParam(required = false) String cover){
        boolean b = articleService.modifyArticle(articleId, content, title, type, cover);
        if (b){
            return JSONUtil.toJSONString(ResultUtil.success());
        }
        return JSONUtil.toJSONString(ResultUtil.error("修改失败！"));
    }
}
